package cn.accjiyun.controller.production;

import cn.accjiyun.common.controller.BaseController;
import cn.accjiyun.common.entity.PageModel;
import cn.accjiyun.common.entity.QueryEntity;
import cn.accjiyun.common.utils.WebUtils;
import cn.accjiyun.entity.json.Output;
import cn.accjiyun.entity.json.Price;
import cn.accjiyun.entity.json.Yield;
import cn.accjiyun.entity.production.Producer;
import cn.accjiyun.service.production.LandService;
import cn.accjiyun.service.production.ProducerService;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.sun.javafx.charts.Legend;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.*;

/**
 * Created by jiyun on 2017/5/3.
 */
@Controller
@RequestMapping("/admin/production")
public class AdminProducerController extends BaseController {
    private static Logger logger = LoggerFactory.getLogger(AdminProducerController.class);
    private static String addProducerPage = getViewPath("/admin/production/producer-add");
    private static String producerListPage = getViewPath("/admin/production/producer-list");
    private static String statisticsPage = getViewPath("/admin/statistics/statistics");

    @Autowired
    private ProducerService producerService;
    @Autowired
    private LandService landService;

    @InitBinder({"producer"})
    public void initBinderSysUser(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("producer.");
    }

    /**
     * 创建生产信息
     *
     * @return Map<String, Object>
     */
    @RequestMapping("/createProducer")
    @ResponseBody
    public String createProducer(HttpServletRequest request) {
        JsonObject resultJson = new JsonObject();
        try {
            String producerName = request.getParameter("producerName");
            Double area = Double.valueOf(request.getParameter("area"));
            String producerType = request.getParameter("producerType");
            String varietyName = request.getParameter("varietyName");
            Integer batchDuration = Integer.valueOf(request.getParameter("batchDuration"));
            String principalName = request.getParameter("principalName");
            Integer batchId = Integer.valueOf(request.getParameter("batchId"));
            Integer plannedYield = Integer.valueOf(request.getParameter("plannedYield"));
            Double plannedPrice = Double.valueOf(request.getParameter("plannedPrice"));
            Double plannedTotalPrice = Double.valueOf(request.getParameter("plannedTotalPrice"));
            Integer realYield = Integer.valueOf(request.getParameter("realYield"));
            Double realPrice = Double.valueOf(request.getParameter("realPrice"));
            Double realTotalPrice = Double.valueOf(request.getParameter("realTotalPrice"));
            Byte isProduced = Byte.valueOf(request.getParameter("isProduced"));
            Timestamp startTime = WebUtils.stringToTimestamp(request.getParameter("startTime"));
            Timestamp endTime = WebUtils.stringToTimestamp(request.getParameter("endTime"));
            String comments = request.getParameter("comments");

            Producer producer = new Producer();
            producer.setProducerName(producerName);
            producer.setArea(area);
            producer.setProducerType(producerType);
            producer.setVarietyName(varietyName);
            producer.setBatchDuration(batchDuration);
            producer.setPrincipalName(principalName);
            producer.setBatchId(batchId);
            producer.setPlannedYield(plannedYield);
            producer.setPlannedPrice(plannedPrice);
            producer.setPlannedTotalPrice(plannedTotalPrice);
            producer.setRealYield(realYield);
            producer.setRealPrice(realPrice);
            producer.setRealTotalPrice(realTotalPrice);
            producer.setIsProduced(isProduced);
            producer.setStartTime(startTime);
            producer.setEndTime(endTime);
            producer.setComments(comments);

            producerService.createProducer(producer);
            resultJson.addProperty("status", 200);
            resultJson.addProperty("msg", "添加成功");
            resultJson.addProperty("url", "/admin/production/producerList");
        } catch (Exception e) {
            logger.error("AdminProducer.createProducer()--error", e);
            resultJson.addProperty("status", 400);
            resultJson.addProperty("msg", "添加失败！");
        }
        logger.info(gson.toJson(resultJson));
        return gson.toJson(resultJson);
    }

    @RequestMapping("/deleteProducer")
    @ResponseBody
    public String deleteProducer(HttpServletRequest request) {
        JsonObject resultJson = new JsonObject();
        try {
            String[] producerIdsString = request.getParameter("producerId").split(",");
            int[] producerIds = new int[producerIdsString.length];
            for (int i = 0; i < producerIdsString.length; i++) {
                producerIds[i] = Integer.valueOf(producerIdsString[i]);
            }
            if (producerIdsString != null && producerIdsString.length > 0) {
                producerService.deleteProducer(producerIds);
            }
            resultJson.addProperty("status", 200);
            resultJson.addProperty("msg", "删除成功");
            resultJson.addProperty("url", "reload");
        } catch (Exception e) {
            logger.error("AdminProducerController.deleteProducer()--error", e);
            resultJson.addProperty("status", 400);
            resultJson.addProperty("msg", "删除失败！");
        }
        logger.info(gson.toJson(resultJson));
        return gson.toJson(resultJson);
    }

    /**
     * 分页查询生产信息
     *
     * @param request
     * @return
     */
    @RequestMapping("/getProducerList")
    @ResponseBody
    public String getProducerList(HttpServletRequest request) {
        JsonObject resultJson = new JsonObject();
        try {
            QueryEntity queryEntity = new QueryEntity();
            Map eqParams = new HashMap();
            Map likeStrings = new HashMap();
            String producerType = request.getParameter("producerType");
            if (WebUtils.isValidateRealString(producerType)) {
                eqParams.put("producerType", producerType);
            }
            String keyword = request.getParameter("keyword");
            if (WebUtils.isValidateRealString(keyword)) {
                likeStrings.put("producerName", keyword);
                likeStrings.put("principalName", keyword);
                likeStrings.put("varietyName", keyword);
            }
            queryEntity.setEqParams(eqParams);
            queryEntity.setLikeStrings(likeStrings);
            queryEntity.setBeginCreateTime(WebUtils.stringToData(request.getParameter("start_date")));
            queryEntity.setEndCreateTime(WebUtils.stringToData(request.getParameter("end_date")));
            queryEntity.setDateKeyword("startTime");
            PageModel<Producer> page = new PageModel();
            page.setPageSize(5);
            int pageNo = Integer.valueOf(request.getParameter("pageNo"));
            page.setPageNo(pageNo);
            List<Producer> producerList = producerService.queryProducerPage(queryEntity, page);
            JsonArray array = new JsonArray();
            for (Producer producer : producerList) {
                JsonObject list = new JsonObject();
                list.addProperty("producerId", producer.getProducerId());
                list.addProperty("producerName", producer.getProducerName());
                list.addProperty("area", producer.getArea());
                list.addProperty("producerType", producer.getProducerType());
                list.addProperty("varietyName", producer.getVarietyName());
                list.addProperty("batchDuration", producer.getBatchDuration());
                list.addProperty("principalName", producer.getPrincipalName());
                list.addProperty("batchId", producer.getBatchId());
                list.addProperty("plannedYield", producer.getPlannedYield());
                list.addProperty("plannedPrice", producer.getPlannedPrice());
                list.addProperty("plannedTotalPrice", producer.getPlannedTotalPrice());
                list.addProperty("realYield", producer.getRealYield());
                list.addProperty("realPrice", producer.getRealPrice());
                list.addProperty("realTotalPrice", producer.getRealTotalPrice());
                list.addProperty("isProduced", producer.getIsProduced());
                list.addProperty("startTime", WebUtils.timestampToString(producer.getStartTime()));
                list.addProperty("endTime", WebUtils.timestampToString(producer.getEndTime()));
                list.addProperty("comments", producer.getComments());
                array.add(list);
            }
            resultJson.addProperty("status", 200);
            resultJson.addProperty("pages", page.getTotalPageSize());
            JsonObject list = new JsonObject();
            list.add("list", array);
            resultJson.add("data", list);
        } catch (Exception e) {
            logger.error("AdminProducerController.getProducerList()--error", e);
            resultJson.addProperty("status", 400);
            resultJson.addProperty("msg", "获取列表失败！");
        }
        logger.info(gson.toJson(resultJson));
        return gson.toJson(resultJson);
    }

    @RequestMapping("/updateProducer")
    @ResponseBody
    public String updateProducer(HttpServletRequest request) {
        JsonObject resultJson = new JsonObject();
        try {
            int producerId = Integer.valueOf(request.getParameter("producerId"));
            String producerName = request.getParameter("producerName");
            Double area = Double.valueOf(request.getParameter("area"));
            String producerType = request.getParameter("producerType");
            String varietyName = request.getParameter("varietyName");
            Integer batchDuration = Integer.valueOf(request.getParameter("batchDuration"));
            String principalName = request.getParameter("principalName");
            Integer batchId = Integer.valueOf(request.getParameter("batchId"));
            Integer plannedYield = Integer.valueOf(request.getParameter("plannedYield"));
            Double plannedPrice = Double.valueOf(request.getParameter("plannedPrice"));
            Double plannedTotalPrice = Double.valueOf(request.getParameter("plannedTotalPrice"));
            Integer realYield = Integer.valueOf(request.getParameter("realYield"));
            Double realPrice = Double.valueOf(request.getParameter("realPrice"));
            Double realTotalPrice = Double.valueOf(request.getParameter("realTotalPrice"));
            Byte isProduced = Byte.valueOf(request.getParameter("isProduced"));
            Timestamp startTime = WebUtils.stringToTimestamp(request.getParameter("startTime"));
            Timestamp endTime = WebUtils.stringToTimestamp(request.getParameter("endTime"));
            String comments = request.getParameter("comments");

            Producer producer = producerService.queryProducerById(producerId);
            producer.setProducerName(producerName);
            producer.setArea(area);
            producer.setProducerType(producerType);
            producer.setVarietyName(varietyName);
            producer.setBatchDuration(batchDuration);
            producer.setPrincipalName(principalName);
            producer.setBatchId(batchId);
            producer.setPlannedYield(plannedYield);
            producer.setPlannedPrice(plannedPrice);
            producer.setPlannedTotalPrice(plannedTotalPrice);
            producer.setRealYield(realYield);
            producer.setRealPrice(realPrice);
            producer.setRealTotalPrice(realTotalPrice);
            producer.setIsProduced(isProduced);
            producer.setStartTime(startTime);
            producer.setEndTime(endTime);
            producer.setComments(comments);

            producerService.updateProducer(producer);
            resultJson.addProperty("status", 200);
            resultJson.addProperty("url", "reload");
            resultJson.addProperty("msg", "更新成功");
        } catch (Exception e) {
            logger.error("AdminProducer.update()--error", e);
            resultJson.addProperty("status", 400);
            resultJson.addProperty("msg", "更新失败！");
        }
        logger.info(gson.toJson(resultJson));
        return gson.toJson(resultJson);
    }

    @RequestMapping("/producerAdd")
    public ModelAndView initUserAddPage() {
        ModelAndView model = new ModelAndView();
        model.addObject("landList", landService.getLandList());
        model.setViewName(addProducerPage);
        return model;
    }

    @RequestMapping("/producerList")
    public ModelAndView initUserListPage() {
        ModelAndView model = new ModelAndView();
        model.setViewName(producerListPage);
        return model;
    }

    @RequestMapping("/outputCharts.json")
    @ResponseBody
    public String getOutput() {
        List<Object[]> productions = producerService.querySumGroupBy("realTotalPrice", "producerType");
        Output output = new Output();
        Output.LegendBean legend = new Output.LegendBean();
        List<String> legendData = new ArrayList<>();
        List<Output.DataBean> dataList = new ArrayList<>();
        for (Object[] o : productions) {
            String name = new String((String) o[1]);
            double value = (Double) o[2];
            legendData.add(name);
            Output.DataBean dataBean = new Output.DataBean();
            dataBean.setName(name);
            dataBean.setValue(value);
            dataList.add(dataBean);
        }
        output.setData(dataList);
        legend.setData(legendData);
        output.setLegend(legend);
        logger.info(gson.toJson(output));
        return gson.toJson(output);
    }

    @RequestMapping("/yieldChart.json")
    @ResponseBody
    public String getYield() {
        Object[] queryParams = {};
        String hql = "select p.varietyName, sum(p.realYield),year(p.endTime) from Producer  as p where p.isProduced = 1  group by year(p.endTime),p.varietyName order by endTime";
        List<Object[]> productions = producerService.createQuery(hql, queryParams);
        Yield yield = new Yield();
        int maxYear = 0;
        int minYear = 9999;
        Map<String, List<Long>> seriesListMap = new TreeMap<>();
        Set<String> varietyNameSet = new TreeSet<>();
        for (Object[] o : productions) {
            String varietyName = (String) o[0];
            int year = (int) o[2];
            if (year > maxYear) maxYear = year;
            if (year < minYear) minYear = year;
            varietyNameSet.add(varietyName);
        }

        //legend--data
        Yield.LegendBean legend = new Yield.LegendBean();
        List<String> legendData = new ArrayList<>();
        legendData.addAll(varietyNameSet);
        legend.setData(legendData);
        yield.setLegend(legend);

        //xAxis--data
        List<String> xAxisData = new ArrayList<>();
        for (int year = minYear; year <= maxYear; year++) {
            xAxisData.add(String.valueOf(year));
        }
        Yield.XAxisBean xAxis = new Yield.XAxisBean();
        xAxis.setData(xAxisData);
        yield.setXAxis(xAxis);

        for (String varietyName : varietyNameSet) {
            List<Long> yearList = new ArrayList<>(
                    Collections.nCopies(maxYear - minYear + 1, new Long(0))
            );
            seriesListMap.put(varietyName, yearList);
        }
        for (Object[] o : productions) {
            String varietyName = (String) o[0];
            long realYield = (long) o[1];
            int year = (int) o[2];
            List<Long> yearList = seriesListMap.get(varietyName);
            yearList.set(year - minYear, realYield);
        }
        List<Yield.SeriesBean> series = new ArrayList<>();
        for (Map.Entry<String, List<Long>> entry : seriesListMap.entrySet()) {
            Yield.SeriesBean seriesBean = new Yield.SeriesBean();
            seriesBean.setName(entry.getKey());
            seriesBean.setType("line");
            seriesBean.setData(entry.getValue());
            series.add(seriesBean);
        }
        yield.setSeries(series);
        logger.info(gson.toJson(yield));
        return gson.toJson(yield);
    }

    @RequestMapping("/priceChart.json")
    @ResponseBody
    public String getPrice() {
        Object[] queryParams = {};
        String hql = "select p.varietyName, sum(p.realPrice),year(p.endTime) from Producer as p where p.isProduced = 1 group by year(p.endTime),p.varietyName order by endTime";
        List<Object[]> productions = producerService.createQuery(hql, queryParams);
        Price price = new Price();
        int maxYear = 0;
        int minYear = 9999;
        Map<String, List<Double>> seriesListMap = new TreeMap<>();
        Set<String> varietyNameSet = new TreeSet<>();
        for (Object[] o : productions) {
            String varietyName = (String) o[0];
            int year = (int) o[2];
            if (year > maxYear) maxYear = year;
            if (year < minYear) minYear = year;
            varietyNameSet.add(varietyName);
        }

        //legend--data
        Price.LegendBean legend = new Price.LegendBean();
        List<String> legendData = new ArrayList<>();
        legendData.addAll(varietyNameSet);
        legend.setData(legendData);
        price.setLegend(legend);

        //xAxis--data
        List<String> xAxisData = new ArrayList<>();
        for (int year = minYear; year <= maxYear; year++) {
            xAxisData.add(String.valueOf(year));
        }
        Price.XAxisBean xAxis = new Price.XAxisBean();
        xAxis.setData(xAxisData);
        price.setXAxis(xAxis);

        for (String varietyName : varietyNameSet) {
            List<Double> yearList = new ArrayList<>(
                    Collections.nCopies(maxYear - minYear + 1, new Double(0))
            );
            seriesListMap.put(varietyName, yearList);
        }
        for (Object[] o : productions) {
            String varietyName = (String) o[0];
            double realPrice = (double) o[1];
            int year = (int) o[2];
            List<Double> yearList = seriesListMap.get(varietyName);
            yearList.set(year - minYear, realPrice);
        }
        List<Price.SeriesBean> series = new ArrayList<>();
        for (Map.Entry<String, List<Double>> entry : seriesListMap.entrySet()) {
            Price.SeriesBean seriesBean = new Price.SeriesBean();
            seriesBean.setName(entry.getKey());
            seriesBean.setType("line");
            seriesBean.setData(entry.getValue());
            series.add(seriesBean);
        }
        price.setSeries(series);
        logger.info(gson.toJson(price));
        return gson.toJson(price);
    }

    @RequestMapping("/statisticsPage")
    public ModelAndView statisticsPage() {
        ModelAndView model = new ModelAndView();
        model.setViewName(statisticsPage);
        return model;
    }

}

